import axios from 'axios'
axios.defaults.headers.post['Content-Type'] = 'application/json';
const toLogin = async () => {
  const microApp = window.__MicroAPP__;
  if(microApp) {
    microApp.bus.$emit({
      eventName: microApp.keys.UserLogin
    })
  }
}
axios.interceptors.request.use(config => {
  let token = window.__MicroAPP__?.user.token;
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
}, error => {
  return Promise.reject(error);
});
axios.interceptors.response.use(response => {
  const { data } = response;
  if (data != null && data.code === -2) {
    toLogin();
  }
  return data;
}, error => {
  const { response: { status, data } } = error;
  if (status === 401 || status === 403 || (data != null && data.code === -2)) {
    toLogin()
  }
  return Promise.reject(error);
});
const factory = (obj:any) => {
  let output: HttpType = {} as HttpType;
  Object.keys(obj).forEach(methodKey => {
    Object.keys(obj[methodKey]).forEach((apiKey: string) => {
      let api = obj[methodKey][apiKey];
      output[apiKey] = function (data:any, args:any, cb:any) {
        /**
         * @param args.controller
         * @description 取消请求
         * 
         * @param args.timeout
         * @description 设置超时时间
         */
        const mathes = api.match(/:[a-zA-Z_]+/g)
        mathes && mathes.forEach((math: string) => {
          if(!data) return;
          api = api.replace(new RegExp(math, 'g'), data[math.substring(1)])
        })
        switch (methodKey) {
          case 'get':
            for(const key in data) {
                const val = data[key];
                if(typeof val === 'object'){
                  data[key] = JSON.stringify(val)
                }
              }
              return axios.get(api, {
                params: data,
                signal: args?.controller?.signal,
                ...(args?.timeout ? {timeout: args.timeout} : {})
              });
          case 'post':
            return axios.post(`${api}`, data, {
              ...args,
              signal: args?.controller?.signal,
              ...(args?.timeout ? {timeout: args.timeout} : {})
            })
          case 'delete':
            return axios.delete(`${api}`, {data})
          case 'file':
            return axios.post(`${api}`, data, {
              headers: {
                'content-type': 'multipart/form-data',
                ...args.headers
              },
              onUploadProgress: cb
            })
          default:
            return null
        }
      }
    })
  })
  return output;
}
export default factory
